﻿#include <iostream>
#include <string>
#include <thread>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
#pragma warning(disable: 4996)

int main()
{
    // 1.初始化Winsock
    WSADATA ws;
    WSAStartup(MAKEWORD(2,2), &ws);

    // 2. 创建套接字
    int server = socket(AF_INET, SOCK_DGRAM, 0);
    if (server == -1) {
        cout << "创建套接字失败:" << errno << endl;
        return -1;
    }

    // 3.初始化套接字,设置地址和端口
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = htons(8000);

    // 4.设置套接字属性,为广播类型
    bool optval = true;
    setsockopt(server, SOL_SOCKET, SO_BROADCAST,  (const char*)&optval, sizeof(optval));

    // 5.绑定端口
    int bindRet = bind(server, (sockaddr*)&addr, sizeof(addr));

    cout << "UDP服务端运行中..." << endl;
    int addrSize = sizeof(addr);
    while (true)
    {
        char buf[100] = { 0 };
        // 6.接收信息
        int reRet = recvfrom(server, buf, sizeof(buf), 0, (sockaddr*)&addr, &addrSize);
        if (reRet == -1) {
            cout << "连接失败:" << errno << endl;
            break;
        }
        cout << "连接成功:" << inet_ntoa(addr.sin_addr) << ":" << addr.sin_port << endl;
        cout << "接收到信息:" << buf << endl;
        // 7.发送数据
        strcpy(buf, "我是UDP服务器!");
        int seRet = sendto(server, buf, sizeof(buf), 0, (sockaddr*)&addr, sizeof(addr));
        if (seRet == -1) {
            cout << "发送失败:" << errno << endl;
            break;
        }
        cout << "发送成功." << endl;
    }
    // 8.关闭套接字
    closesocket(server);
    return 0;
}